package org.pp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.pp.core.AdminConstants;
import org.pp.core.Assertion;
import org.pp.entity.SysMenu;
import org.pp.entity.SysRoleMenu;
import org.pp.mapper.SysMenuMapper;
import org.pp.service.ISysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.pp.service.ISysRoleMenuService;
import org.pp.util.RedisUtil;
import org.pp.vo.AdminMenuTreeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>
 * 权限（菜单） 服务实现类
 * </p>
 *
 * @author haima
 * @since 2024-04-16
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    ISysRoleMenuService roleMenuService;

    private List<AdminMenuTreeVo> tree(List<SysMenu> list) {
        // pid  - > list
        //准备，把这个映射关系放入Map
        Map<Long, List<SysMenu>> mp = new ConcurrentHashMap<>();
        for (SysMenu sysMenu : list) {
            //pid,本身
            if (!mp.containsKey(sysMenu.getPid())) {
                mp.put(sysMenu.getPid(), new ArrayList<>());
            }
            mp.get(sysMenu.getPid()).add(sysMenu);
        }
        //挑选出第一级的菜单
        List<SysMenu> root = list.stream().filter(e -> e.getPid().equals(0L)).toList();
        List<AdminMenuTreeVo> rootVo = BeanUtil.copyToList(root, AdminMenuTreeVo.class);
        tree(rootVo, mp);
        return rootVo;
    }

    private void tree(List<AdminMenuTreeVo> rootVo, Map<Long, List<SysMenu>> mp) {
        for (AdminMenuTreeVo vo : rootVo) {
            List<SysMenu> sysMenus = mp.get(vo.getMenuId());
            if (Objects.nonNull(sysMenus)) {
                List<AdminMenuTreeVo> chidren = BeanUtil.copyToList(sysMenus, AdminMenuTreeVo.class);
                vo.setChildren(chidren);
                tree(vo.getChildren(), mp);
            }
        }
    }


    @Override
    public List<AdminMenuTreeVo> tree() {
        List<SysMenu> list = list();
        return tree(list);
    }


    @Override
    public List<AdminMenuTreeVo> tree(Collection<Long> menuIds) {
        List<SysMenu> sysMenus = listByIds(menuIds);
        return tree(sysMenus);
    }

    @Override
    @Transactional
    public void delete(String ids) {
        List<String> list = Arrays.asList(ids.split(","));
        if(CollectionUtil.isEmpty(list)){
            return;
        }
        long count = count(new LambdaQueryWrapper<SysMenu>()
                .in(SysMenu::getPid, list)
        );
        List<SysMenu> sysMenus = listByIds(list);
        Map<Long,SysMenu> sysMenuMap= new ConcurrentHashMap<>();
        for (SysMenu sysMenu : sysMenus) {
            sysMenuMap.put(sysMenu.getMenuId(),sysMenu);
        }
        Assertion.gtZeroThrow(count,"不能删除有子节点的菜单或目录");

        //删除关联关系
        roleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getMenuId,list));

        List<SysRoleMenu> roleMenus = roleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>()
                .in(SysRoleMenu::getMenuId, list));

        Map<Long , List<String>> mp= new ConcurrentHashMap<>();
        for (SysRoleMenu roleMenu : roleMenus) {
            if(!mp.containsKey(roleMenu.getRoleId())){
                mp.put(roleMenu.getRoleId(),new ArrayList<>());
            }
            mp.get(roleMenu.getRoleId()).add(sysMenuMap.get(roleMenu.getMenuId()).getApi());
        }
        mp.forEach((k,v)->{
            redisUtil.removeMembers(AdminConstants.roleAuths+":"+k,  ArrayUtil.toArray(v,String.class));
        });

        removeBatchByIds(list);
    }


}
